package com.bjpowernode.shop.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bjpowernode.shop.base.BaseManagerService;
import com.bjpowernode.shop.constants.CommonConstants;
import com.bjpowernode.shop.domain.SysUser;
import com.bjpowernode.shop.domain.SysUserRole;
import com.bjpowernode.shop.log.anno.Log;
import org.apache.commons.lang.ObjectUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Nullable;
import javax.management.relation.RelationNotFoundException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/sys/user")
public class SysUserController extends BaseManagerService {

    // ==查询当前登录用户的用户信息==
    @GetMapping("/info")
    public ResponseEntity getInfo() {
        return ResponseEntity.ok(
                // 根据用户id查询指定字段信息
                sysUserService.getOne(
                        new LambdaQueryWrapper<SysUser>()
                                .select(SysUser::getUserId, SysUser::getUsername)
                                .eq(SysUser::getUserId, getLongUserId())
                )
        );
    }

    // ==分页模糊查询 管理员列表信息==
    @GetMapping("/page")
    @PreAuthorize("hasAuthority('sys:user:page')")
    public ResponseEntity<Page<SysUser>> getUserPage(Page<SysUser> page, @RequestParam(value = "username", required = false) String username) {
        return ResponseEntity.ok(
                sysUserService.page(
                        page, new LambdaQueryWrapper<SysUser>()
                                .like(StringUtils.hasText(username), SysUser::getUsername, username)
                ));
    }

    // ==新增用户 管理员列表信息==
    @PostMapping
    @PreAuthorize("hasAuthority('sys:user:save')")
    @Transactional
    @Log(operation = "新增用户 管理员列表信息")
    public ResponseEntity<Boolean> saveUser(@RequestBody SysUser sysUser) {
        boolean flag = sysUserService.save(
                sysUser.setCreateUserId(getLongUserId())
                        .setCreateTime(new Date())
                        .setShopId(CommonConstants.DEFAULT_SHOP_ID)
                        .setPassword(new BCryptPasswordEncoder().encode(sysUser.getPassword()))
        );

        // 统一异常处理
        if (!flag) {
            throw new RuntimeException("新增用户失败");
        }

        // 根据用户对象中的角色id列表RoleIdList，构建出用户和角色的关联关系表userRoleList
        // roleIdList【前端传过来，后端用sysUser接收，为sysUser新增roleIdList字段】
        List<SysUserRole> userRoleList = sysUser.getRoleIdList().stream().map(
                roleId -> {
                    return SysUserRole.builder()
                            .userId(sysUser.getUserId())
                            .roleId(roleId)
                            .build();
                }
        ).collect(Collectors.toList());

        // 批量新增关联关系表
        sysUserRoleService.saveBatch(userRoleList);

        return ResponseEntity.ok(flag);
    }

    // ==修改用户 管理员列表信息==
    // 查询指定用户的用户信息
    @GetMapping("/info/{id}")
    public ResponseEntity<SysUser> getInfo(@PathVariable Long id) {
        // 根据用户userid查询userRole关联列表
        List<SysUserRole> userRoleList = sysUserRoleService.list(
                new LambdaQueryWrapper<SysUserRole>()
                        .eq(
                                StringUtils.hasText(String.valueOf(id)),
                                SysUserRole::getUserId,
                                id
                        )
        );
        // 将关联列表给出的roleId整合到List集合中
        List<Long> roleIdList = new ArrayList<>();
        for (SysUserRole sysUserRole : userRoleList) {
            roleIdList.add(sysUserRole.getRoleId());
        }

        // 查询指定用户的用户信息
        SysUser sysUser = sysUserService.getById(id);
        // 补充数据库中查不到的roleIdList数据
        sysUser.setRoleIdList(roleIdList);

        System.out.println("getInfoSysUser = " + sysUser);
        return ResponseEntity.ok(
                sysUser
                // 根据指定用户id查询用户全信息
                // sysUserService.getById(id)
        );
    }

    // 提交修改信息表单
    @PutMapping
    @Transactional
    public ResponseEntity<Boolean> updateSysUser(@RequestBody SysUser sysUser) {

        System.out.println("====sysUser = " + sysUser);

        boolean flag = sysUserService.updateById(sysUser
                .setPassword(new BCryptPasswordEncoder().encode(sysUser.getPassword()))
        );

        System.out.println("====updateSysUser-flag = " + flag);

        if (!flag)
            throw new RuntimeException("修改用户失败");

        // 查询修改后的关联列表
        List<SysUserRole> userRoleList = sysUser.getRoleIdList().stream().map(
                roleId -> {
                    return SysUserRole.builder()
                            .userId(sysUser.getUserId())
                            .roleId(roleId)
                            .build();
                }
        ).collect(Collectors.toList());

        System.out.println("====updateuserRoleList = " + userRoleList);

        // 删除原关联列表
        boolean flag1 = sysUserRoleService.remove(
                new LambdaQueryWrapper<SysUserRole>().eq(
                        SysUserRole::getUserId, sysUser.getUserId()
                )
        );

        if (!flag1)
            throw new RuntimeException("删除原关联失败");

        // 批量新增关联列表
        boolean flag2 = sysUserRoleService.saveOrUpdateBatch(userRoleList);

        if (!flag2)
            throw new RuntimeException("新增关联失败");

        // 返回结果
        return ResponseEntity.ok(flag);
    }

    @DeleteMapping("/{ids}")
    @Transactional
    public ResponseEntity<Boolean> delSysUser(@PathVariable("ids") List<Long> ids) {
        System.out.println("===ids = " + ids);
        
        // 删除用户【逻辑删除，数据库中行数据仍在】
        boolean flag1 = sysUserService.removeByIds(ids);

        if (!flag1) {
            throw new RuntimeException("删除用户失败");
        }

        // 删除原关联列表
        for (Long id : ids) {
            boolean flag2 = sysUserRoleService.remove(
                    new LambdaQueryWrapper<SysUserRole>().eq(
                            SysUserRole::getUserId, id
                    )
            );
            if (!flag2)
                throw new RuntimeException("删除原关联失败");
        }
        
        // 返回结果
        return ResponseEntity.ok(flag1);
    }
}
